/**
 * 
 */
package com.pmsco.pms.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.pmsco.pms.ajaxdata.CategoryListJsonData;
import com.pmsco.pms.ajaxdata.SubCategoryJsonData;
import com.pmsco.pms.ajaxdata.SubCategoryListJsonData;
import com.pmsco.pms.annotation.LogonRequired;
import com.pmsco.pms.annotation.PermissionRequired;
import com.pmsco.pms.business.CategoryBusiness;
import com.pmsco.pms.business.dto.CategoryRequestDTO;
import com.pmsco.pms.business.dto.CategoryReturnDTO;
import com.pmsco.pms.business.dto.SubCategoryRequestDTO;
import com.pmsco.pms.business.dto.SubCategoryReturnDTO;
import com.pmsco.pms.core.constant.PmsConstant;
import com.pmsco.pms.core.domain.Category;
import com.pmsco.pms.core.domain.SubCategory;
import com.pmsco.pms.util.PmsLogonRequired;
import com.pmsco.pms.util.PmsPermissionRequired;

/**
 * @author Long Tran
 *
 */
@Controller
public class PmsCategoryController extends AbstractPmsController {
	private static final Logger logger = LoggerFactory.getLogger(PmsCategoryController.class);
	
	/**
	 * List PMS Category
	 */
	@RequestMapping(value = PmsConstant.listCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_LIST_CATEGORY_FUNCTION)
	public String listCategory(Locale locale, Model model) {
		logger.info("List Category Action");
		return PmsConstant.listCategory_View;
	}
	
	/**
	 * List PMS Category Data
	 */
	@RequestMapping(value = PmsConstant.listCategoryData_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_LIST_CATEGORY_FUNCTION)
	public @ResponseBody CategoryListJsonData listCategoryData(HttpServletRequest request, Locale locale, Model model) {
		logger.info("Begin List Category Data Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Build list category request dto");
		CategoryRequestDTO categoryRequestDTO = new CategoryRequestDTO();
		Integer page = Integer.parseInt(request.getParameter("page"));
		Integer rows = Integer.parseInt(request.getParameter("rows"));
		String sidx = request.getParameter("sidx");
		String sord = request.getParameter("sord");
		String searchField = request.getParameter("searchField");
		String searchString = request.getParameter("searchString");
		String searchOper = request.getParameter("searchOper");
		if(page == null)
			page = 1;
		if(rows == null)
			rows = 10;
		categoryRequestDTO.setPage(page);
		categoryRequestDTO.setRows(rows);
		categoryRequestDTO.setSidx(sidx);
		categoryRequestDTO.setSord(sord);
		categoryRequestDTO.setSearchField(searchField);
		categoryRequestDTO.setSearchString(searchString);
		categoryRequestDTO.setSearchOper(searchOper);
		
		logger.debug("Call to pms category business for list category");
		CategoryReturnDTO categoryReturnDTO = categoryBusiness.listCategoryData(categoryRequestDTO);
		
		logger.debug("Analysis list category return dto");
		CategoryListJsonData categoryListJsonData = new CategoryListJsonData();
		Integer records = categoryReturnDTO.getCategoriesSize();
		Integer total = (records / rows);
		if(records % rows > 0)
			total += 1;
		categoryListJsonData.setPage(page);
		categoryListJsonData.setRecords(records);
		categoryListJsonData.setTotal(total);
		List<Category> data = new ArrayList<Category>();
		for(Category category : categoryReturnDTO.getCategories()) {
			data.add(category);
		}
		categoryListJsonData.setRows(data);
		
		logger.info("End List Category Data Action");
		return categoryListJsonData;
	}
	
	/**
	 * Edit PMS Category
	 */
	@RequestMapping(value = PmsConstant.editCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_EDIT_CATEGORY_FUNCTION)
	public ModelAndView editCategory(@RequestParam(value = "id") Long id) {
		logger.info("Begin Edit Category Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Build edit category request dto");
		CategoryRequestDTO categoryRequestDTO = new CategoryRequestDTO();
		categoryRequestDTO.setCategoryId(id);
		
		logger.debug("Call to category business for edit menu");
		CategoryReturnDTO categoryReturnDTO = categoryBusiness.editCategory(categoryRequestDTO);
		
		logger.debug("Analysis create category return dto");
		ModelAndView ret = new ModelAndView(categoryReturnDTO.getReturnView(), "command", categoryReturnDTO.getCategory());
		
		logger.info("End Edit Category Action");
		return ret;
	}
	
	/**
	 * Create PMS Category
	 */
	@RequestMapping(value = PmsConstant.createCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_CREATE_CATEGORY_FUNCTION)
	public ModelAndView createCategory(Locale locale, Model model) {
		logger.info("Begin Create Category Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Call to category business for create category");
		CategoryReturnDTO categoryReturnDTO = categoryBusiness.createCategory(new CategoryRequestDTO());
		
		logger.debug("Analysis create category return dto");
		ModelAndView ret = new ModelAndView(categoryReturnDTO.getReturnView(), "command", categoryReturnDTO.getCategory());
		
		logger.info("End Create Category Action");
		return ret;
	}
	
	/**
	 * Save PMS Category
	 */
	@RequestMapping(value = PmsConstant.saveCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_SAVE_CATEGORY_FUNCTION)
	public ModelAndView saveCategory(@ModelAttribute("categoryDetail") Category categoryDetail, Locale locale, Model model, HttpServletRequest request) {
		logger.info("Begin Save Category Action");
		CategoryBusiness cateogryBusiness = new CategoryBusiness();
		
		logger.debug("Build save category request dto");
		CategoryRequestDTO categoryRequestDTO = new CategoryRequestDTO();
		
		categoryRequestDTO.setDirtyCategory(categoryDetail);
		
		logger.debug("Call to category business for save cateogry");
		CategoryReturnDTO categoryReturnDTO = cateogryBusiness.saveCategory(categoryRequestDTO);
		
		logger.debug("Analysis save category return dto");
		ModelAndView ret = null;
		if(categoryReturnDTO.getReturnUrl() != null && !categoryReturnDTO.getReturnUrl().isEmpty()) {
			ret = new ModelAndView(new RedirectView(categoryReturnDTO.getReturnUrl()));
		} else {
			ret = new ModelAndView(categoryReturnDTO.getReturnView(), "command", categoryReturnDTO.getCategory());
			ret.addObject(PmsConstant.errorMessage, categoryReturnDTO.getErrorMessage());
		}
		logger.info("End Save Category Action");
		return ret;
	}
	
	/**
	 * Delete category
	 */
	@RequestMapping(value = PmsConstant.deleteCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_DELETE_CATEGORY_FUNCTION)
	public ModelAndView deleteCategory(Locale locale, Model model, HttpServletRequest request) {
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		logger.info("Begin Delete Category Action");
		String selectedCategoryIds = request.getParameter("selectedCategoryIds");
		String cannotDeleteCategoryIds = categoryBusiness.deleteCategories(selectedCategoryIds);
		ModelAndView ret = new ModelAndView(new RedirectView(PmsConstant.listCategory_View));
		if(!cannotDeleteCategoryIds.isEmpty())
			ret.addObject(PmsConstant.errorCode, PmsConstant.constraintError);
		logger.info("End Delete Category Action");
		return ret;
	}
	
	/**
	 * List PMS Sub Category
	 */
	@RequestMapping(value = PmsConstant.listSubCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_LIST_SUB_CATEGORY_FUNCTION)
	public String listSubCategory(Locale locale, Model model) {
		logger.info("List Sub Category Action");
		return PmsConstant.listSubCategory_View;
	}
	
	/**
	 * List PMS Sub Category Data
	 */
	@RequestMapping(value = PmsConstant.listSubCategoryData_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_LIST_SUB_CATEGORY_FUNCTION)
	public @ResponseBody SubCategoryListJsonData listSubCategoryData(HttpServletRequest request, Locale locale, Model model) {
		logger.info("Begin List Sub Category Data Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Build list sub category request dto");
		SubCategoryRequestDTO subCategoryRequestDTO = new SubCategoryRequestDTO();
		Integer page = Integer.parseInt(request.getParameter("page"));
		Integer rows = Integer.parseInt(request.getParameter("rows"));
		String sidx = request.getParameter("sidx");
		String sord = request.getParameter("sord");
		String searchField = request.getParameter("searchField");
		String searchString = request.getParameter("searchString");
		String searchOper = request.getParameter("searchOper");
		if(page == null)
			page = 1;
		if(rows == null)
			rows = 10;
		subCategoryRequestDTO.setPage(page);
		subCategoryRequestDTO.setRows(rows);
		subCategoryRequestDTO.setSidx(sidx);
		subCategoryRequestDTO.setSord(sord);
		subCategoryRequestDTO.setSearchField(searchField);
		subCategoryRequestDTO.setSearchString(searchString);
		subCategoryRequestDTO.setSearchOper(searchOper);
		
		logger.debug("Call to pms category business for list category");
		SubCategoryReturnDTO subCategoryReturnDTO = categoryBusiness.listSubCategoryData(subCategoryRequestDTO);
		
		logger.debug("Analysis list sub category return dto");
		SubCategoryListJsonData subCategoryListJsonData = new SubCategoryListJsonData();
		Integer records = subCategoryReturnDTO.getSubCategoriesSize();
		Integer total = (records / rows);
		if(records % rows > 0)
			total += 1;
		subCategoryListJsonData.setPage(page);
		subCategoryListJsonData.setRecords(records);
		subCategoryListJsonData.setTotal(total);
		List<SubCategoryJsonData> data = new ArrayList<SubCategoryJsonData>();
		for(SubCategory subCategory : subCategoryReturnDTO.getSubCategories()) {
			data.add(new SubCategoryJsonData(subCategory));
		}
		subCategoryListJsonData.setRows(data);
		
		logger.info("End List Sub Category Data Action");
		return subCategoryListJsonData;
	}
	
	/**
	 * Edit PMS Sub Category
	 */
	@RequestMapping(value = PmsConstant.editSubCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_EDIT_SUB_CATEGORY_FUNCTION)
	public ModelAndView editSubCategory(@RequestParam(value = "id") Long id) {
		logger.info("Begin Edit Sub Category Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Build edit sub category request dto");
		SubCategoryRequestDTO subCategoryRequestDTO = new SubCategoryRequestDTO();
		subCategoryRequestDTO.setSubCategoryId(id);
		
		logger.debug("Call to category business for edit sub category");
		SubCategoryReturnDTO subCategoryReturnDTO = categoryBusiness.editSubCategory(subCategoryRequestDTO);
		
		logger.debug("Analysis create sub category return dto");
		ModelAndView ret = new ModelAndView(subCategoryReturnDTO.getReturnView(), "command", subCategoryReturnDTO.getSubCategory());
		ret.addObject(PmsConstant.categoryList, subCategoryReturnDTO.getCategoryList());
		
		logger.info("End Edit Sub Category Action");
		return ret;
	}
	
	/**
	 * Create PMS Sub Category
	 */
	@RequestMapping(value = PmsConstant.createSubCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_CREATE_SUB_CATEGORY_FUNCTION)
	public ModelAndView createSubCategory(Locale locale, Model model) {
		logger.info("Begin Create Sub Category Action");
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		
		logger.debug("Call to category business for create sub category");
		SubCategoryReturnDTO subCategoryReturnDTO = categoryBusiness.createSubCategory(new SubCategoryRequestDTO());
		
		logger.debug("Analysis create sub category return dto");
		ModelAndView ret = new ModelAndView(subCategoryReturnDTO.getReturnView(), "command", subCategoryReturnDTO.getSubCategory());
		ret.addObject(PmsConstant.categoryList, subCategoryReturnDTO.getCategoryList());
		
		logger.info("End Create Sub Category Action");
		return ret;
	}
	
	/**
	 * Save PMS Sub Category
	 */
	@RequestMapping(value = PmsConstant.saveSubCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_SAVE_SUB_CATEGORY_FUNCTION)
	public ModelAndView saveSubCategory(@ModelAttribute("subCategoryDetail") SubCategory subCategoryDetail, Locale locale, Model model, HttpServletRequest request) {
		logger.info("Begin Save Sub Category Action");
		CategoryBusiness cateogryBusiness = new CategoryBusiness();
		
		logger.debug("Build save sub category request dto");
		SubCategoryRequestDTO subCategoryRequestDTO = new SubCategoryRequestDTO();
		
		Long categoryId = Long.valueOf(request.getParameter("categoryId"));
		if(categoryId.intValue() > 0) {
			subCategoryRequestDTO.setCategoryId(categoryId);
		}
		
		subCategoryRequestDTO.setDirtySubCategory(subCategoryDetail);
		
		logger.debug("Call to category business for save sub cateogry");
		SubCategoryReturnDTO subCategoryReturnDTO = cateogryBusiness.saveSubCategory(subCategoryRequestDTO);
		
		logger.debug("Analysis save sub category return dto");
		ModelAndView ret = null;
		if(subCategoryReturnDTO.getReturnUrl() != null && !subCategoryReturnDTO.getReturnUrl().isEmpty()) {
			ret = new ModelAndView(new RedirectView(subCategoryReturnDTO.getReturnUrl()));
		} else {
			ret = new ModelAndView(subCategoryReturnDTO.getReturnView(), "command", subCategoryReturnDTO.getSubCategory());
			ret.addObject(PmsConstant.errorMessage, subCategoryReturnDTO.getErrorMessage());
		}
		logger.info("End Save Sub Category Action");
		return ret;
	}
	
	/**
	 * Delete sub category
	 */
	@RequestMapping(value = PmsConstant.deleteSubCategory_Url)
	@LogonRequired(required = PmsLogonRequired.ADMIN_USER)
	@PermissionRequired(required = PmsPermissionRequired.PMS_DELETE_SUB_CATEGORY_FUNCTION)
	public ModelAndView deleteSubCategory(Locale locale, Model model, HttpServletRequest request) {
		CategoryBusiness categoryBusiness = new CategoryBusiness();
		logger.info("Begin Delete Sub Category Action");
		String selectedSubCategoryIds = request.getParameter("selectedSubCategoryIds");
		String cannotDeleteSubCategoryIds = categoryBusiness.deleteSubCategories(selectedSubCategoryIds);
		ModelAndView ret = new ModelAndView(new RedirectView(PmsConstant.listSubCategory_View));
		if(!cannotDeleteSubCategoryIds.isEmpty())
			ret.addObject(PmsConstant.errorCode, PmsConstant.constraintError);
		logger.info("End Delete Sub Category Action");
		return ret;
	}
}
